/*
 * $Id$
 */
package org.crazydays.wowarmory;


import java.io.IOException;
import java.net.URI;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * WowArmoryHttpClient
 */
public class WowArmoryHttpClient
{
	/** user agent */
	public final static String PROP_USER_AGENT = "httpClient.userAgent";

	/** log */
	protected final static Log LOG = LogFactory.getLog(WowArmoryHttpClient.class);

	/** http client */
	protected HttpClient httpClient = new HttpClient();

	/**
	 * WowArmoryHttpClient constructor.
	 */
	public WowArmoryHttpClient()
	{
		init();
	}

	/**
	 * Initialize.
	 */
	protected final void init()
	{
	}

	/**
	 * Get http client.
	 *
	 * @return HttpClient
	 */
	protected synchronized HttpClient getHttpClient()
	{
		return httpClient;
	}

	/**
	 * Get page.
	 *
	 * @param page Page
	 * @return Page
	 * @throws WowArmoryException
	 */
	public <T extends IPage> T getPage(T page)
		throws WowArmoryException
	{
		HttpMethod httpMethod = getHttpMethod(page);

		// set retry
		httpMethod.getParams().setParameter(
			HttpMethodParams.RETRY_HANDLER, 
			new DefaultHttpMethodRetryHandler(3, false));

		try {
			int status = getHttpClient().executeMethod(httpMethod);
			if (status != HttpStatus.SC_OK) {
				throw new WowArmoryException(
					"Invalid HttpState").setPage(page).
						setStatus(status);
			}

			// bytes
			byte[] bytes = httpMethod.getResponseBody();
			page.setBytes(bytes);

			return page;
		} catch (HttpException e) {
			LOG.error(e);
			throw new WowArmoryException(e).setPage(page);
		} catch (IOException e) {
			LOG.error(e);
			throw new WowArmoryException(e).setPage(page);
		} finally {
			httpMethod.releaseConnection();
		}
	}

	/**
	 * Get http method.
	 *
	 * @param page Page
	 * @return HttpMethod
	 */
	protected HttpMethod getHttpMethod(IPage page)
	{
		if (page == null) {
			throw new IllegalArgumentException("page == null");
		}

		URI uri = page.getPageUri();
		if (uri == null) {
			throw new IllegalStateException("uri == null");
		}

		return new GetMethod(uri.toString());
	}
}
